import { bytesToSize } from '@/utils/index';
import { useMessage } from 'naive-ui';
import { v4 as uuidv4 } from 'uuid';
import { ref, computed, Ref, ComputedRef } from 'vue';
import { uploadImage } from '@/api/intelligent';
import { is99Mall, isHQSC, isHZL, isSaaS } from '@/utils/is';
import { TOKEN_LOGIN_KEY, TOKEN_STORE_KEY } from '@/enums/cacheEnum'
import { local_storage } from '@/utils/storage';

interface Props {
  rules: Ref<{
    size: number
    rect: [number, number] | [number]
    duration: [number, number],
  } & any> | ComputedRef<{
    size: number
    rect: [number, number] | [number]
    duration: [number, number],
  } & any>
}
function useUpload(props: Props) {
  const message = useMessage();
  const uploadRef = ref();

  function sizeValidate(file: any, rules: any) {
    const rulesSize = rules ? (rules.size || 100) : (props.rules.value.size || 100)
    if (rulesSize && (file.size) > (rulesSize * 1024)) {
      return false;
    }
    return true;

  }

  function proportionValidate(file: { width: number, height: any } & any, rules: any) {
    const rulesRect = rules ? (rules.rect || []) : props.rules.value.rect || [];
    if (!rulesRect.length) return true;
    if (rulesRect.length === 1) {
      return (file.width + 5 > rulesRect[0]) || (file.height + 5 > rulesRect[0]);
    }
    const [width, height] = rulesRect;
    const _width = Math.abs(width - file.width)
    const _height = Math.abs(height - file.height);
    if (width && (_width > 5 || _height > 5)) {
      return false
    }


    return true;
  }


  function videoDurationValidate(file: { duration: number } & any, rules: any) {
    const rulesDuration = rules ? (rules.duration || []) : props.rules.value.duration || [];
    if (!rulesDuration.length) return true;
    if (!(file.duration <= rulesDuration[1] && file.duration >= rulesDuration[0])) {
      return false;
    }
    return true;
  }



  function getFileType(file: any) {

    const fileBody = file.file;

    if (fileBody.type.indexOf('image') !== -1) {
      return 'image'

    } else if (fileBody.type.indexOf('video') !== -1) {
      return 'video'
    }
    return 'other'
  }


  function getImageInfo(file: any): any {
    return new Promise((resolve, reject) => {
      const URL = window.URL || window.webkitURL;
      const originFile = file.file;
      const src = URL.createObjectURL(originFile)
      const image = new Image()
      image.src = src
      image.onload = () => {
        resolve({
          width: image.width,
          height: image.height
        })
      }
      image.onerror = () => {
        reject({
          width: 0,
          height: 0
        })
      }

    })


  }

  function getVideoInfo(file: any): any {
    return new Promise((resolve, reject) => {
      const URL = window.URL || window.webkitURL;
      const originFile = file.file;

      const src = URL.createObjectURL(originFile)
      const video = document.createElement('video');

      video.src = src
      video.oncanplay = () => {
        resolve({
          width: video.videoWidth,
          duration: video.duration,
          height: video.videoHeight
        })
      }
      video.onerror = () => {
        reject({
          width: 0,
          duration: 0,
          height: 0
        })
      }

    })

  }

  async function validate(file: any, rules?: any) {
    const rect = props.rules.value.rect || [];
    const duration = props.rules.value.duration || [];
    const originFile = file.file;
    const metaType = getFileType(file);
    uploadRef.value && uploadRef.value.clear();

    if (!sizeValidate(originFile, rules)) {
      message.warning(`请上传≤${bytesToSize(props.rules.value.size)}的素材`)
      return undefined;
    }
    const info = metaType === 'image' ? await getImageInfo(file) : await getVideoInfo(file);
    if (!proportionValidate(info, rules)) {
      // console.log(rect, 'rect');
      const isRangeTag = rect.length == 1 ? '≥' : '';
      message.warning(`请上传推荐尺寸 ${isRangeTag}${rect[0]}px X ${rect[1] || rect[0]}px 的素材`);
      return undefined;
    }
    if (metaType === 'video' && !videoDurationValidate(info, rules)) {
      message.warning(`当前视频时长为：${info.duration}s，不符合要求, 应该为≥${duration[0]}s，≤${duration[1] || duration[0]}s, 请重新上传`);
      return undefined;
    }
    return {
      id: file.id,
      file: file.file,
      batchId: file.batchId,
      imageWidth: info.width,
      imageHeight: info.height,
      meta_type: metaType,
      // mediaType: 1,
      fileSize: originFile.size,
      uuid: uuidv4()

    }
  }

  function createRequestMedia(data: any) {
    if (data.media_id || data.mediaId || data.imageId || data.fileUrl || data.previewUrl) {
      const refile = {
        ...data,
        media_url: data.previewUrl,
        mediaId: '' + data.mediaId,
        media_id: '' + data.mediaId,
      };
      return refile
    }
    return {};

  }

  async function uploadCover(media: any, query: any) {
    if (media.meta_type === 'video') {
      const res = await uploadImage({
        accountCode: query.accountCode,
        keyFrameImageUrl: media.keyFrameImageUrl
      });
      media.cover_id = res.data.mediaId;
      return media;
    }
    return media;
  }

  const rulesTips = computed(() => {
    const { duration, file_format, size } = props.rules.value;
    const filetext = (file_format || []).map(_ => {
      return _.replace(/MEDIA_TYPE_|IMAGE_TYPE_/, '');
    }).join('/');
    const [durMin, durMax] = duration || [];
    const durtext = duration && duration.length ? `，时长≥${durMin}s，≤${durMax}s，必须带有声音` : '';
    const sizetext = +size ? `，<${ size < 1024 ? size + 'K' : ((size || 0) / 1024).toFixed(2) + 'M'}` : '';
    return `${filetext}${sizetext}${durtext}`;
  });

  const accept = computed(() => {
    const { file_format } = props.rules.value;
    return (file_format || []).map(_ => {
      return '.' + _.replace(/MEDIA_TYPE_|IMAGE_TYPE_/, '');
    }).join(',')
  });

  const headers = computed(() => {
    const System = is99Mall ? 1 : isHZL ? 2 : isHQSC ? 3 : isSaaS ? 4 : null
    return {
      accessToken: local_storage.get(TOKEN_STORE_KEY) || local_storage.get(TOKEN_LOGIN_KEY),
      'x-system': System,
    }
  })

  return {
    rulesTips,
    createRequestMedia,
    uploadCover,
    validate,
    getFileType,
    uploadRef,
    headers,
    accept
  }

}

export { useUpload }
